package com.cjkj.system.service.impl;

import com.cjkj.common.core.constant.EquipmentConstants;
import com.cjkj.common.core.constant.HttpStatus;
import com.cjkj.common.core.constant.SecurityConstants;
import com.cjkj.common.core.domain.R;
import com.cjkj.common.core.exception.ServiceException;
import com.cjkj.common.core.utils.DateUtils;
import com.cjkj.common.core.utils.StringUtils;
import com.cjkj.common.core.utils.bean.BeanUtils;
import com.cjkj.common.security.utils.SecurityUtils;
import com.cjkj.system.api.RemoteTJ02DataService;
import com.cjkj.system.api.domain.APIHospitalEquipment;
import com.cjkj.system.api.domain.APISmartBraceletData;
import com.cjkj.system.api.domain.THospitalDept;
import com.cjkj.system.api.domain.dto.APIEquipmentStatusDto;
import com.cjkj.system.api.domain.request.LatestDatasReq;
import com.cjkj.system.api.domain.request.LatestDatasReqEquipmentInfo;
import com.cjkj.system.api.model.LoginUser;
import com.cjkj.system.domain.THospitalEquipment;
import com.cjkj.system.domain.dto.EquipmentDistributionInfo;
import com.cjkj.system.domain.dto.HospitalEquipmentDistributionReq;
import com.cjkj.system.domain.dto.HospitalEquipmentOptionsParam;
import com.cjkj.system.domain.dto.HospitalEquipmentReq;
import com.cjkj.system.domain.vo.HospitalEquipmentOptionsVo;
import com.cjkj.system.domain.vo.HospitalEquipmentVo;
import com.cjkj.system.mapper.THospitalDeptMapper;
import com.cjkj.system.mapper.THospitalEquipmentMapper;
import com.cjkj.system.service.ITHospitalEquipmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 医院分配的设备Service业务层处理
 * 
 * @author cjkj
 * @date 2024-08-30
 */
@Service
@Slf4j
public class THospitalEquipmentServiceImpl implements ITHospitalEquipmentService 
{
    @Resource
    private THospitalEquipmentMapper tHospitalEquipmentMapper;

    @Resource
    private THospitalDeptMapper tHospitalDeptMapper;

    @Resource
    private RemoteTJ02DataService remoteTJ02DataService;

    @Override
    public APIHospitalEquipment getHospitalEquipment(String equipmentId) {
        THospitalEquipment tHospitalEquipment = tHospitalEquipmentMapper.selectByEquipmentId(equipmentId);

        APIHospitalEquipment equipment = new APIHospitalEquipment();
        if(tHospitalEquipment != null) {
            BeanUtils.copyBeanProp(equipment, tHospitalEquipment);
        }
        return equipment;
    }

    @Override
    public int updateEquipmentStatus(APIEquipmentStatusDto statusDto) {
        THospitalEquipment equipment = new THospitalEquipment();
        equipment.setEquipmentId(statusDto.getEquipmentId());
        equipment.setFailureFlag(statusDto.getFailureFlag());
        equipment.setFailureStartTime(statusDto.getFailureTime());
        if(tHospitalEquipmentMapper.updateEquipmentStatus(equipment) < 0){
            throw new ServiceException("更新设备状态错误");
        }
        return 1;
    }

    @Override
    public String distributionEquipment(HospitalEquipmentDistributionReq req) {
        List<EquipmentDistributionInfo> equipmentList = req.getEquipmentList();
        String hospitalId = req.getHospitalId();
        String deptId = req.getDeptId();
        if (StringUtils.isNull(equipmentList) || equipmentList.isEmpty())
        {
            throw new ServiceException("设备不能为空！");
        }
        if(StringUtils.isBlank(hospitalId)){
            throw new ServiceException("未能识别用户所属医院，请重新登录后再试！");
        }
        if(StringUtils.isNotBlank(deptId)){
            THospitalDept tHospitalDept = tHospitalDeptMapper.selectByHosIdAndId(hospitalId, deptId);
            if(tHospitalDept == null){
                throw new ServiceException("选择的部门有误！");
            }
        }
        String opName = SecurityUtils.getUsername();
        Date nowDate = DateUtils.getNowDate();

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for(EquipmentDistributionInfo distributionInfo : equipmentList){
            try {
                THospitalEquipment temp = tHospitalEquipmentMapper.selectByIdAndHosId(distributionInfo.getId(), hospitalId);
                if( temp == null){
                    failureNum ++;
                    failureMsg.append("<br/>").append(failureNum).append("、设备号 ").append(distributionInfo.getEquipmentNo()).append(" 不存在！");
                } else {
                    if(EquipmentConstants.H_EQUIPMENT_USE_FLAG_INUSE.equals(temp.getUseFlag())){
                        failureNum ++;
                        failureMsg.append("<br/>").append(failureNum).append("、设备号 ").append(distributionInfo.getEquipmentNo()).append(" 使用中");
                    } else {

                        temp.setHospitalId(hospitalId);
                        if(StringUtils.isNotBlank(deptId)){
                            temp.setAllocationFlag(EquipmentConstants.EQUIPMENT_ALLOCATION_FLAG_ALLOCATED);
                        } else {
                            temp.setAllocationFlag(EquipmentConstants.EQUIPMENT_ALLOCATION_FLAG_UNALLOTTED);
                        }

                        temp.setDeptId(deptId);
                        temp.setUpdateBy(opName);
                        temp.setUpdateTime(nowDate);

                        int count = tHospitalEquipmentMapper.distributionEquipment(temp);
                        if(count > 0){
                            successNum ++;
                            successMsg.append("<br/>").append(successNum).append("、设备号 ").append(distributionInfo.getEquipmentNo()).append(" 分配成功");
                        } else {
                            failureNum ++;
                            failureMsg.append("<br/>").append(failureNum).append("、设备号 ").append(distributionInfo.getEquipmentNo()).append(" 分配失败");
                        }
                    }
                }
            } catch (Exception e) {
                failureNum ++;
                String msg = "<br/>" + failureNum + "、设备号 " + distributionInfo.getEquipmentNo() + " 分配失败";
                failureMsg.append(msg).append(e.getMessage());
                log.error(msg,e);
            }
        }
        if(failureNum > 0){
            failureMsg.insert(0,"很抱歉，分配失败! 共 " + failureNum+" 条数据格式不正确，错误如下： ");
            throw new ServiceException(failureMsg.toString());
        }else {
            successMsg.insert(0,"设备全部分配成功! 共" + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 查询医院分配的设备列表
     * 
     * @param req 查询条件
     * @return 医院分配的设备
     */
    @Override
    public List<HospitalEquipmentVo> selectTHospitalEquipmentList(HospitalEquipmentReq req)
    {
        List<HospitalEquipmentVo> hospitalEquipmentVos = tHospitalEquipmentMapper.selectEquipmentList(req);

        if(EquipmentConstants.EQUIPMENT_TYPE_SMART_BRACELET_TYPE.equals(req.getEquipmentType())) {
            // 遍历设备数据，查询最新电量数据
            if(! hospitalEquipmentVos.isEmpty()) {
                // 所有设备
                List<LatestDatasReqEquipmentInfo> equipmentInfos = hospitalEquipmentVos.stream().map(hospitalEquipment -> {
                    LatestDatasReqEquipmentInfo equipmentInfo = new LatestDatasReqEquipmentInfo();
                    equipmentInfo.setEquipmentNo(hospitalEquipment.getEquipmentNo());
                    equipmentInfo.setCreateTime(hospitalEquipment.getCreateTime());
                    return equipmentInfo;
                }).collect(Collectors.toList());

                LatestDatasReq params = new LatestDatasReq(null, null, new Date(), 1);
                params.setEquipmentList(equipmentInfos);
                // 远程调用查询所有设备的最新数据
                R<List<APISmartBraceletData>> result = remoteTJ02DataService.getLatestDatas(params, SecurityConstants.INNER);
                List<APISmartBraceletData> dataList = result.getData();
                if (result.getCode() == HttpStatus.SUCCESS && ! dataList.isEmpty()) {
                    for (HospitalEquipmentVo equipment : hospitalEquipmentVos) {
                        for (APISmartBraceletData data : dataList) {
                            if(data != null
                                    && StringUtils.isNotBlank(data.getEquipmentNo())
                                    && data.getEquipmentNo().equals(equipment.getEquipmentNo())) {
                                equipment.setBatteryPercentage(data.getBatteryPercentage());
                                equipment.setAcquisitionTime(data.getAcquisitionTime());
                            }
                        }
                    }
                }
            }
        }

        return hospitalEquipmentVos;
    }

    @Override
    public List<Map<String, Integer>> getExpireData(String equipmentType) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return tHospitalEquipmentMapper.selectExpireData(equipmentType, loginUser.getHospitalId(), loginUser.getDeptId());
    }

    @Override
    public List<Map<String, String>> getFaultyEquipment(String equipmentType) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return tHospitalEquipmentMapper.selectFaultyEquipment(equipmentType, loginUser.getHospitalId(), loginUser.getDeptId());
    }

    @Override
    public List<HospitalEquipmentOptionsVo> getEquipmentOptionData(String equipmentType) {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        HospitalEquipmentOptionsParam param = new HospitalEquipmentOptionsParam();
        param.setEquipmentType(equipmentType);
        param.setHospitalId(loginUser.getHospitalId());
        param.setDeptId(loginUser.getDeptId());

        return tHospitalEquipmentMapper.selectEquipmentOptionData(param);
    }
}
